// Includes
#include <nds.h>
#include <dswifi9.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "wifitest.h"

#include "MSGothic.h"
#include "PMingLiU.h"
#include "SimSun.h"

#include "HttpSocket.h"

void WifiTest::startup() {
	
	delete defaultGadgetStyle->font;
	defaultGadgetStyle->font = new PropackFont(SimSun,SimSun_Size);
			
	/* Code below creates the output screen and associated gadgets */
	// Create screen
	AmigaScreen* outScreen = new AmigaScreen("Ouput Screen", true, false);
	woopsiApplication->addGadget(outScreen);
	
	// Move output screen to top display
	outScreen->flipToTopScreen();
	
	// Create skinned window
	AmigaWindow* reqWindow = new AmigaWindow(0, 13 , 256, 192-13, "Request Header", false, true);
	outScreen->addGadget(reqWindow);
	
		
	// Get available area within window
	Rect rect;
	reqWindow->getClientRect(rect);
	
	// Add textbox
	_reqout = new ScrollingTextBox(rect.x, rect.y, rect.width, rect.height, "", 50);
	_reqout->setTextAlignmentHoriz(MultiLineTextBox::TEXT_ALIGNMENT_HORIZ_LEFT);
	_reqout->setTextAlignmentVert(MultiLineTextBox::TEXT_ALIGNMENT_VERT_TOP);
	_reqout->disableKeyboardPopup();
	reqWindow->addGadget(_reqout);
	
	// Create skinned window
	AmigaWindow* outWindow = new AmigaWindow(0, 13 , 256, 192-13, "Ouput Window", false, true);
	outScreen->addGadget(outWindow);
		
			
	// Get available area within window
	outWindow->getClientRect(rect);
		
	// Add textbox
	_output = new ScrollingTextBox(rect.x, rect.y, rect.width, rect.height, "", 500);
	_output->setTextAlignmentHoriz(MultiLineTextBox::TEXT_ALIGNMENT_HORIZ_LEFT);
	_output->setTextAlignmentVert(MultiLineTextBox::TEXT_ALIGNMENT_VERT_TOP);
	_output->disableKeyboardPopup();
	outWindow->addGadget(_output);
		
	/* Code below creates input screen and associated gadgets */
	// Create screen
	AmigaScreen* inScreen = new AmigaScreen("Input Screen", true, false);
	woopsiApplication->addGadget(inScreen);

	_addressbox = new TextBox(0, 14, 220, 24, "http://wow.fishome.org");
	_addressbox->setTextAlignmentHoriz(TextBox::TEXT_ALIGNMENT_HORIZ_LEFT);
	_addressbox->setTextAlignmentVert(TextBox::TEXT_ALIGNMENT_VERT_CENTRE);
	_addressbox->showCursor();
	_addressbox->disableKeyboardPopup();
	inScreen->addGadget(_addressbox);
		
	_gobutton = new Button(222, 16, 32, 20, "Go");
	_gobutton->addGadgetEventHandler(this);
	inScreen->addGadget(_gobutton);
	
	// Create keyboard
	_keyboard = new WoopsiKeyboard(3, 38, 0);
	_keyboard->addKeyboardEventHandler(_addressbox);
	_keyboard->addKeyboardEventHandler(this);
	inScreen->addGadget(_keyboard);
	
	_addressbox->disable();
	_gobutton->disable();
	_keyboard->disable();
	
	_output->setText("Simple Wifi Connection Demo\nConnecting via WFC data ...\n");
	if(!Wifi_InitDefault(WFC_CONNECT)) {
		_output->appendText("Failed to connect!\n");
	}else{
		_output->appendText("Connected!\n");
		_addressbox->enable();
		_gobutton->enable();
		_keyboard->enable();
	}
}

void WifiTest::shutdown() {

	// Call base shutdown method
	Woopsi::shutdown();
}

void WifiTest::handleClickEvent(const GadgetEventArgs& e) {
	char url[256];
	_reqout->setText("");
	_output->setText("");
	_addressbox->getText().copyToCharArray(url);
	if (e.getSource() == _gobutton) {
		getHttp(url);
	}
	_reqout->jump(0,0);
	_output->jump(0,0);
}

void WifiTest::handleKeyboardPressEvent(const KeyboardEventArgs& e) {
	char url[256];
	if (e.getKey()->getKeyType() == WoopsiKey::KEY_RETURN) {
		_reqout->setText("");
		_output->setText("");
		_addressbox->getText().copyToCharArray(url);
		getHttp(url);
	}
	_reqout->jump(0,0);
	_output->jump(0,0);
}

static int parse_url(char *url, char *serverstrp, int *portp, char **pathstrp)
{
  char buf[256];
  int serverlen, numread=0;
  /* go through the url */

  /* reset url to point PAST the http:// */

  /* assume it''s always 7 chars! */

  if(strstr(url, "http://") == url) url = url+7;
  /* no http:// now... server is simply up to the next / or : */

  sscanf(url, "%255[^/:]", buf);
  serverlen = strlen(buf);
  strcpy(serverstrp, buf);
  if(url[serverlen]==':')
  {
    /* get the port */

    sscanf(&url[serverlen+1], "%d%n", portp, &numread);
    /* add one to go PAST it */

    numread++;
  }
  else
  {
    *portp = 80;
  }
  /* the path is a pointer into the rest of url */

  *pathstrp = &url[serverlen+numread];
  return 0;
}

//---------------------------------------------------------------------------------
void WifiTest::getHttp(char* url) {
//---------------------------------------------------------------------------------
    // Let's send a simple HTTP request to a server and print the results!
	
	CHttpSocket HttpSocket;
	char strServer[256],*strObject;
	int nPort;
	long nLength;
	
	parse_url(url,strServer,&nPort,&strObject);
	
	HttpSocket.FormatRequestHeader(strServer,strObject,nLength);
	HttpSocket.Socket();
	HttpSocket.Connect(strServer,nPort);
	HttpSocket.SendRequest();
	HttpSocket.SetTimeout(10000,0);
	
	int nLineSize = 0;
	char szLine[256];
	while(nLineSize != -1){
		nLineSize = HttpSocket.GetResponseLine(szLine,256);
		if(nLineSize > -1){
			szLine[nLineSize] = '\0';
			_reqout->appendText(szLine);
		}
	}

	char szValue[30];
	HttpSocket.GetField("Content-Length",szValue,30);
	int nSvrState = HttpSocket.GetServerState();
	int nFileSize = atoi(szValue);
	
	int nCompletedSize = 0;
	char pData[1024];
	int nReceSize = 0;
	while(nCompletedSize < nFileSize){
		nReceSize = HttpSocket.Receive(pData,1024);
		if(nReceSize == 0){
			_output->appendText("\nServer closed.\n");
			break;
		}
		if(nReceSize == -1){
			_output->appendText("\nReceive timeout.\n");
			break;
		}
		pData[nReceSize] = '\0';
		_output->appendText(pData);
		nCompletedSize += nReceSize;
	}

	HttpSocket.CloseSocket();
}
